using MediatR;
using Microsoft.Extensions.Logging;
using S.O.Api.Write.Application.Command.Medical;
using S.O.Domain.Medical;
using S.O.ErrorCode;
using S.O.Interstructrue.Base;

namespace S.O.Api.Write.Application.Handler.Medical
{
    /// <summary>
    /// 创建病历记录处理器
    /// 负责处理病历创建的业务逻辑，包括数据验证、病历记录创建和持久化
    /// </summary>
    public class CreateMedicalRecordHandler : IRequestHandler<CreateMedicalRecordCommand, APIResult<string>>
    {
        /// <summary>
        /// 病历信息仓储接口
        /// </summary>
        private readonly IBaseRepository<MedicalRecordModel> _medicalRecordRepository;

        /// <summary>
        /// 患者信息仓储接口
        /// </summary>
        private readonly IBaseRepository<PatientModel> _patientRepository;

        /// <summary>
        /// 日志记录器
        /// </summary>
        private readonly ILogger<CreateMedicalRecordHandler> _logger;

        /// <summary>
        /// 构造函数，通过依赖注入初始化仓储和日志服务
        /// </summary>
        /// <param name="medicalRecordRepository">病历信息仓储</param>
        /// <param name="patientRepository">患者信息仓储</param>
        /// <param name="logger">日志记录器</param>
        public CreateMedicalRecordHandler(
            IBaseRepository<MedicalRecordModel> medicalRecordRepository,
            IBaseRepository<PatientModel> patientRepository,
            ILogger<CreateMedicalRecordHandler> logger)
        {
            _medicalRecordRepository = medicalRecordRepository;
            _patientRepository = patientRepository;
            _logger = logger;
        }

        /// <summary>
        /// 处理创建病历记录命令
        /// </summary>
        /// <param name="request">创建病历记录命令</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>病历记录ID</returns>
        public async Task<APIResult<string>> Handle(CreateMedicalRecordCommand request, CancellationToken cancellationToken)
        {
            try
            {
                _logger.LogInformation("开始处理病历创建请求，患者ID: {PatientId}, 患者姓名: {PatientName}", 
                    request.PatientId, request.PatientName);

                // 验证患者是否存在
                var patient = _patientRepository.GetALL()
                    .FirstOrDefault(p => p.Id == request.PatientId && !p.IsDeleted);
                if (patient == null)
                {
                    _logger.LogWarning("患者不存在，患者ID: {PatientId}", request.PatientId);
                    return new APIResult<string>
                    {
                        Code = APIEnums.Error,
                        Msg = "患者信息不存在"
                    };
                }

                // 验证患者姓名是否匹配
                if (patient.PatientName != request.PatientName)
                {
                    _logger.LogWarning("患者姓名不匹配，数据库中姓名: {DbName}, 请求中姓名: {RequestName}", 
                        patient.PatientName, request.PatientName);
                    return new APIResult<string>
                    {
                        Code = APIEnums.Error,
                        Msg = "患者姓名不匹配"
                    };
                }

                // 生成病历记录ID
                var recordId = GenerateMedicalRecordId();

                // 创建病历记录实体
                var medicalRecord = new MedicalRecordModel
                {
                    Id = recordId,
                    PatientId = request.PatientId,
                    PatientName = request.PatientName,
                    ChiefComplaint = request.ChiefComplaint,
                    PresentIllness = request.PresentIllness,
                    PastHistory = request.PastHistory,
                    AllergyHistory = request.AllergyHistory,
                    PersonalHistory = request.PersonalHistory,
                    FamilyHistory = request.FamilyHistory,
                    PhysicalExam = request.PhysicalExam,
                    AuxiliaryExam = request.AuxiliaryExam,
                    TreatmentAdvice = request.TreatmentAdvice,
                    Doctor = request.Doctor,
                    CreateTime = request.CreateTime,
                    UpdateTime = request.CreateTime,
                    IsEnable = true
                };

                // 保存病历记录到数据库
                var result = _medicalRecordRepository.Create(medicalRecord);

                if (result > 0)
                {
                    _logger.LogInformation("病历创建成功，病历ID: {RecordId}, 患者ID: {PatientId}, 医生: {Doctor}", 
                        recordId, request.PatientId, request.Doctor);

                    return new APIResult<string>
                    {
                        Code = APIEnums.Success,
                        Data = recordId,
                        Msg = "病历创建成功"
                    };
                }
                else
                {
                    _logger.LogError("病历创建失败，数据库保存失败，患者ID: {PatientId}", request.PatientId);
                    return new APIResult<string>
                    {
                        Code = APIEnums.Error,
                        Msg = "病历创建失败，请稍后重试"
                    };
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "创建病历记录时发生异常，患者ID: {PatientId}, 患者姓名: {PatientName}", 
                    request.PatientId, request.PatientName);
                return new APIResult<string>
                {
                    Code = APIEnums.Error,
                    Msg = "创建病历记录失败，请稍后重试"
                };
            }
        }

        /// <summary>
        /// 生成病历记录ID
        /// 格式：MR + 年月日 + 6位序号
        /// 例如：MR20241201000001
        /// </summary>
        /// <returns>病历记录ID</returns>
        private string GenerateMedicalRecordId()
        {
            var datePrefix = DateTime.Now.ToString("yyyyMMdd");
            var timestamp = DateTimeOffset.Now.ToUnixTimeMilliseconds();
            var sequence = (timestamp % 1000000).ToString("D6");
            return $"MR{datePrefix}{sequence}";
        }
    }
}